package com.hlm.transparent.util;


import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Name: ProtocolHelper
 * @Description: ProtocolHelper
 * @Author: jiangcs
 */
@Component
public class ProtocolHelper {
    private static final Map<String, Map<String, Map<String, Object>>> DATA_MAP = new LinkedHashMap<>();

    /**
     * regex
     */
    private static final String REGEX_SECTION = "^\\[\\S+\\]$";
    private static final String REGEX_SECTION_GROUP = "^\\[(\\S+)\\]$";
    private static final String REGEX_PARAMETER = "^.+=.+$";
    /**
     * skip section
     */
    private static final String SKIP_SECTION_GENERAL = "[General]";
    private static final String SKIP_SECTION_COMMAND = "[command]";

    /**
     * 10: EN1434_00XX
     */
    private static final int PROTOCOL_CODE_LENGTH = 10;

    /**
     * 当前 Code、Section
     */
    private static String currentCode = null;
    private static String currentSection = null;

    /**
     * 初始化 parse.ini
     */
    public static void init() {
        try {
            DATA_MAP.clear();

            read( "D:/MyProject/transparent/src/main/resources/parse.ini");

            if (DATA_MAP.size() <= 0) {
                System.err.println("System prompt: protocol ini file load fail");

                System.exit(0);
            } else {
                System.out.println("System prompt: protocol ini file load ok");
            }
        } catch (IOException e) {
            System.err.println("System prompt: protocol ini file load exception");
            e.printStackTrace();

            System.exit(0);
        }
    }

    private static void read(String filePath) throws IOException {
        read(new File(filePath));
    }

    private static void read(File file) throws IOException {
        read(new BufferedReader(new FileReader(file)));
    }

    private static void read(BufferedReader bufferedReader) throws IOException {
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            parseLine(line);
        }
    }

    private static void parseLine(String line) {
        line = line.trim();

        // general | command: 跳过
        if (SKIP_SECTION_GENERAL.equals(line) || SKIP_SECTION_COMMAND.equals(line)) {
            currentCode = null;
            currentSection = null;
        }
        // section
        else if (line.matches(REGEX_SECTION)) {
            addSection(line.replaceFirst(REGEX_SECTION_GROUP, "$1"));
        }
        // parameter
        else if (line.matches(REGEX_PARAMETER)) {
            if (currentCode != null && currentSection != null) {
                addKeyValue(line);
            }
        }
    }

    private static void addSection(String line) {
        if (line.length() <= PROTOCOL_CODE_LENGTH) {
            System.err.println("protocol init file: section[" + line + "].length <= " + PROTOCOL_CODE_LENGTH);
            return;
        }

        int index = line.indexOf("_", PROTOCOL_CODE_LENGTH);
        currentCode = line.substring(0, index);
        currentSection = line.substring(index + 1);

        Map<String, Map<String, Object>> sectionMap;
        if (exists(currentCode)) {
            sectionMap = DATA_MAP.get(currentCode);
        } else {
            sectionMap = new LinkedHashMap<>();

            DATA_MAP.put(currentCode, sectionMap);
        }

        if (!sectionMap.containsKey(currentSection)) {
            sectionMap.put(currentSection, new LinkedHashMap<>());
        }
    }

    private static void addKeyValue(String line) {
        int index = line.indexOf("=");
        String key = line.substring(0, index).trim();
        String value = line.substring(index + 1).trim();
        if (!DATA_MAP.containsKey(currentCode)) {
            return;
        }

        Map<String, Map<String, Object>> sectionMap = DATA_MAP.get(currentCode);
        if (!sectionMap.containsKey(currentSection)) {
            return;
        }

        sectionMap.get(currentSection).put(key, value);
    }

    /**
     * 判断 key 是否存在
     *
     * @param key
     * @return
     */
    public static boolean exists(String key) {
        return DATA_MAP.containsKey(key);
    }

    /**
     * 返回 参数数据
     *
     * @param code
     * @param section
     * @return
     */
    public static Map<String, Object> getParameterMap(String code, String section) {
        Map<String, Map<String, Object>> sectionMap = DATA_MAP.get(code);
        try {
            return sectionMap.get(section);
        }catch(Exception e) {
            e.printStackTrace();
            return null;
        }

    }
}
